就外型而言,Symbol 就像在一組變數前面加上冒號。
就分類而言,symbol 就是 Symbol 這個 class 的 instance。
既然是一個物件,就具備以下特性:
hash
中擔任 key
的腳色hero = { :name => '埼玉', :年紀 => 25 }
hero.keys # 印出 [:name, :年紀]
這是我們昨天尾聲的題目:猜猜這行程式碼有幾個參數?
link_to "⾸頁", root_path, class:"btn btn-default", method: "post", confirm: true
答案是 3個
。我們來還原一下就會更清楚:
link_to "⾸頁", root_path, { :class => "btn btn-default", :method => "post", :confirm => true }
Symbol
:我們用 all_symbols.count
這個方法來驗證看看:
Symbol.all_symbols.count # 印出 4688(每台電腦每個版本可能有差異)
pet = 'doggie'
Symbol.all_symbols.count # 印出 4689
def pet
'kitty'
end
Symbol.all_symbols.count # 印出 4689
pet # 印出 "doggie"
pet() # 印出 "kitty"
以上程式碼可以看出,的確在宣告變數之後 Symbol
就偷偷增加了一個,然而相同的名稱只會產出相同的 Symbol 。你可能會想說這樣 Ruby 為什麼不會搞錯?如果說在 Ruby 裡常常都能省略小括號,現在的情境就是少數省略小括號結果不同的時機,在變數跟方法名稱相同的時候,正確的呼叫才能獲得預期的結果。
Symbol 最常拿來跟 String 比較的原因,也許是兩者在某些狀況能得到相同的結果,又或是說只有 String 擁有to_sym
的方法
擁有相同的方法?
"我是不是很可愛"[1] # 印出 "是"
:我是不是很可愛[1] # 印出 "是"
"我是不是很可愛"[1] = "是真的" # 印出 "是真的"
:我是不是很可愛[1] "是真的" # 印出 undefined method `[]=' for :我是不是很可愛:Symbol
簡單說就是 String 有的方法 Symbol 不一定具備,查詢 Ruby API 會發現 Symbol 的方法遠比 String 少得多,為什麼不使用 String 就好?
這就好像A的優點比B多10倍,但B有1個優點是A所沒有的
,比方說效能上的差異:
3.times do
puts "hello".object_id
end
# 印出以下結果
# 46947784927160
# 46947784925440
# 46947784908240
3.times do
puts :hello.object_id
end
# 印出以下結果
# 1928668
# 1928668
# 1928668
相同的物件會有相同的 object_id,但同樣的 "hello" 卻會得到不同的 object_id,這表示它們在記憶體裡是不同的物件,當第二次要取用同一個 Symbol 的時候,它會直接從記憶體裡拿,而不用重新產生一份,因此 Symbol 相對節省記憶體一些。
參考資料:
為你自己學 Ruby on Rails
此文同步刊登於CJ-Han的網站